<template>
    <a-select
        v-bind="attrs"
        ref="selectRef"
        v-model:value="selectedValue"
        mode="multiple"
        label-in-value
        show-search
        placeholder="请输入"
        :default-active-first-option="false"
        :show-arrow="false"
        :filter-option="false"
        @search="selectSearch"
        @change="selectChange"
        @inputKeyDown="handleInputKeydown"
    >
        <template v-if="loading" #notFoundContent>
            <a-spin size="small" />
        </template>
        <template #notFoundContent v-else-if="slotNames.includes('notFoundContent')">
            <slot name="notFoundContent" :searchValue="searchValue" />
        </template>
        <a-select-option v-for="(item, index) of currOptions" :key="index" :value="item[keyField]" :option="item">
            <slot name="label" :record="item" v-if="slotNames.includes('label')" />
            <span v-else>
                {{ item[label] }}
            </span>
        </a-select-option>
    </a-select>
</template>

<script lang="ts">
import api from '@/api';
import { message } from 'ant-design-vue';
import { debounce, deepClone } from '@/utils/util';
import { defineComponent, ref, unref, reactive, toRefs, watch, onMounted, computed } from 'vue';
export default defineComponent({
    name: 'HSearchSelectCell',
    props: {
        type: { type: String, default: '' }, // 类型，用来区分请求那一类的查询
        valueLabelField: { type: String, default: '' },
        label: { type: String, default: '' }, //下拉显示的字段
        isSupportEnter: { type: Boolean, default: false }, // 是否支持回车
        keyField: { type: String, default: 'manager' }, // 根据该字段筛选
        defaultValue: { type: Array, default: () => [] },
        searchQuery: {
            type: Object,
            default: () => ({})
        }
    },
    emits: ['success', 'update:value', 'error'],
    setup(props, { emit, attrs, slots }) {
        const selectRef = ref<any>();
        const state = reactive<any>({
            currOptions: [],
            attrs: {},
            selectArr: [],
            searchValue: '',
            selectedValue: [],
            loading: false
        });
        const slotNames = computed(() => {
            return Object.keys(slots);
        });
        const getOptions = async (name = '') => {
            state.loading = true;
            let requestApi: any = null;
            let query: any = {};
            switch (props.type) {
                case 'allUser':
                    requestApi = api.userModel.getEmployeeList;
                    break;
                // 根据指定角色查用户
                case 'role':
                    requestApi = api.userModel.findByRole;
                    break;
                case 'allSystem':
                    requestApi = api.productDetailModel.findAll;
                    break;
                // 根据名称查系统设置的标签
                case 'systemLabel':
                    requestApi = api.labelModel.findLabelByName;
                    break;
                case 'reportSystem':
                    requestApi = api.requireReportModel.findUnSetSystemsByName;
                    break;
                case 'jira':
                    requestApi = api.jiraModel.getIssuesByConditions;
                    break;
                case 'jiraVersion':
                    requestApi = api.jiraModel.getVersionByConditions;
                    break;
                case 'systemManager':
                    requestApi = api.systemManagerModel.findManagersBySystem;
                    break;
                case 'findConnectAble':
                    requestApi = api.annualPlanningModel.findConnectAble;
                    break;
                default:
                    '';
            }
            switch (props.type) {
                case 'allUser':
                    query = {
                        pageSize: 100,
                        pageNum: 1,
                        condition: name
                    };
                    break;
                case 'allSystem':
                    query = {
                        name,
                        isGetManager: true,
                        isLineConnect: true
                    };
                    break;
                case 'findConnectAble':
                    query = {
                        content: name,
                        ...props.searchQuery
                    };
                    break;
                default:
                    query = {
                        name,
                        ...props.searchQuery
                    };
            }
            const { success, moule, errorMsg, errorCode } = await requestApi(query);
            if (success) {
                // 组织中心接口改动后，需要兼容旧数据
                if (props.type === 'allUser') {
                    state.currOptions = moule.map((item) => ({
                        label: item[props.label],
                        value: item[props.keyField],
                        ...item,
                        empId: item.userId,
                        empName: item.name
                    }));
                } else {
                    state.currOptions = moule.map((item) => ({
                        label: item[props.label],
                        value: item[props.keyField],
                        ...item
                    }));
                }
            } else {
                emit('error', {
                    errorCode
                });
                message.error(errorMsg);
            }
            state.loading = false;
            return { success, moule };
        };
        // 搜索回调
        const selectSearch = (val) => {
            state.searchValue = val;
            getDebounceOptions(val);
        };
        // 通用选择回调
        const selectChange = (val: Recordable[], options) => {
            state.selectArr = options.map((item, index) => {
                if (item.option) {
                    return item.option;
                } else {
                    return {
                        [props.valueLabelField]: state.selectedValue[index].label
                    };
                }
            });
            console.log('selectArr', state.selectArr);
            emit('success', state.selectArr); // 对应事件
            emit('update:value', state.selectArr); // 对应v-model
        };
        const getDebounceOptions = debounce(getOptions, 300);

        // 监听回车事件
        const handleInputKeydown = ({ code, target }) => {
            // 按下回车键
            if (code === 'Enter' && props.isSupportEnter) {
                const inputValue = target.value;
                state.selectedValue.push({
                    label: inputValue,
                    value: inputValue
                });
                const arr = [
                    ...state.selectArr,
                    {
                        [props.valueLabelField]: inputValue
                    }
                ];
                emit('success', arr);
                emit('update:value', arr); // 对应v-model
                getDebounceOptions();
            }
        };

        // 处理默认值
        watch(
            () => props.defaultValue,
            (n: any) => {
                if (n && n.length) {
                    if (props.keyField) {
                        state.attrs = {
                            ...attrs
                        };
                        state.selectedValue = n.map((item) => ({
                            ...item,
                            label: item[props.valueLabelField],
                            value: item[props.keyField]
                        }));
                        state.selectArr = deepClone(n);
                    }
                } else {
                    state.attrs = {
                        ...attrs
                    };
                    state.selectedValue = [];
                }
            },
            { immediate: true, deep: true }
        );
        watch(
            () => props.searchQuery,
            (n, o) => {
                // 如果最开始是禁用，则无需调用查询接口
                if (!attrs.disabled && JSON.stringify(n) !== JSON.stringify(o)) {
                    // 先请求所有数据
                    getOptions().then(({ success, moule }) => {
                        if (success) {
                            state.currOptions = moule.map((item) => ({
                                ...item
                            }));
                        }
                    });
                }
            },
            {
                deep: true,
                immediate: true
            }
        );
        return {
            ...toRefs(state),
            selectRef,
            selectSearch,
            selectChange,
            slotNames,
            getOptions,
            handleInputKeydown
        };
    }
});
</script>
